#!/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2001,2004 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# sccs = @(#)89   1.27         src/rsct/cfg_access/cfghact.sh, cfg.access, rsct_rzauh, rzauh0431a 12/17/03 20:03:14
#
# usage:
#   cfghact -I/-Z   install/deinstall for AIX
#   cfghact -i [-f] [-x] # after the 1st installation (-x no start)
#   cfghact -U [-x]	# before the upgrade (-x no start)
#   cfghact -u [-f]	# after the upgrade
#   cfghact -z [-x]	# before the uninstallation [-x no stop]
#   cfghact -d [-x]	# delete HATS/HAGS subsystems (only all LCs)
#   cfghact -c <clstname> -n <nodenum> [-f] [-w]
#			# change the cluster name
#
# note:
#   -f stop or restart rmc, and force to update if necessary
#   -x no start or stop (Network Installation)
#   -w wait until all rmc procs are stopped or restarted
#

PATH=/usr/sbin/rsct/install/bin:/usr/sbin/rsct/bin:/usr/bin:/bin:/usr/sbin:/sbin
export PATH

export MSGMAPPATH="/usr/sbin/rsct/msgmaps"
CATFILE=ha_com.cat
MSGCMD="/usr/sbin/rsct/bin/hadspmsg cfgaccess ${CATFILE}"

RSCTBIN=/usr/sbin/rsct/bin
CTROOT=/var/ct

# Link CCAL scripts to cfgmgr if not done already
CCAL_CMDS="ct_hats_info ct_hags_info ct_topology_info \
	   ct_read_machines_lst ct_write_machines_lst"

basecmd=$(basename $0)

#########################################################################
# Get the current Locale and determine whether English output is also needed
# Output: LOCALE
#         PRINT_ENG_MSG
#########################################################################
get_current_locale()
{
   # Check if current locale is a English
   LOCALE=`/usr/bin/locale`
   # /usr/bin/locale may produce LC_MESSAGES=en_US or LC_MESSAGES="en_US".
   # We use two sed "s" commands, the first one gets rid of LC_MESSAGES=,
   # the second one removes the two surrounding '"' if they are there.
   LOCALE=`echo "$LOCALE" | grep LC_MESSAGES | sed "s/LC_MESSAGES=//;s/\"//g"`

   # Do not print English messages if the local language is English.
   # C and POSIX are special locales. Treat them as en_US.
   if [[ "$LOCALE" = "C" || "$LOCALE" = "POSIX" ]]; then
        PRINT_ENG_MSG="NO"
   else
        # A locale may look like en_US or en_US.ISO8859-1. Use cut command
        # to remove the language encoding.
        LOCALE=`echo "$LOCALE" | cut -f 1 -d "."`
        if [[ "$LOCALE" = "en_US" || "$LOCALE" = "En_US" || "$LOCALE" = "en_GB" || "$LOCALE" = "En_GB" ]]
        then
                # Local language is English.
                PRINT_ENG_MSG="NO"
        else
                # Local language is not English (including "$LOCALE"=""),
                # which should not happen in normal cases)
                PRINT_ENG_MSG="YES"
        fi
   fi
}

#########################################################################
#                                                                       #
# Function: print_message                                               #
# Description: wrapper for message printing. All messages go to stderr. #
#     For now, all messages are printed in both English and the current #
#     language unless current language is en_US, C, or POSIX.           #
#                                                                       #
#     This subroutine makes it easy to print messages in  either English#
#     or current language or both. Also, it ensure all messages will be #
#     printed to the same stream.                                       #
#########################################################################

print_message()
{
    MSGCMD2="/usr/sbin/rsct/bin/hadspmsg cfgaccess ha_com.cat"
    print -u2 "`${MSGCMD2} $*`"

#    if [[ $PRINT_ENG_MSG = "YES" ]]
#    then
#        print -u2 "`LC_ALL=en_US ${MSGCMD2} $*`"
#    fi
}


#
function print_dbgmsg
{
   if [[ -n $HA_CCAL_LOG ]]; then
	print `date` ${basecmd}: "$*" >> $HA_CCAL_LOG
   fi
}

#

#***************************************************************************=
function enable_rmc_remote_port
{
    # enable the remote connections
    if [[ -x ${RSCTBIN}/rmcctrl ]]; then
	${RSCTBIN}/rmcctrl -p 2>&1 > /dev/null
	if [[ $? -ne 0 ]]; then
	     # If it fails, make it enabled at the next startup
	     ${RSCTBIN}/rmcctrl -q
	fi
    fi
}

#***************************************************************************=
# return 0 if Non-RPD, or <>0 if RPD
function is_RPD_Name
{
    clname=$1
    if [[  X${clname}X = XIWX ]];
    then
	echo "0"
	return 0
    else
        echo "$1" | grep "-"  2>&1 > /dev/null
        rc=$?
        echo "$rc"
        return $rc
    fi
}

#***************************************************************************=

RSCTGRP=rsct
RMGRP=rsct_rm

# create the initial 'cluster info' when rmc is not installed
# INPUT: cluster_name node_number 
function create_cluster_info_files
{
   clustername=$1	# cluster_name
   nodenum=$2		# node number
   print_dbgmsg "create cluster=$clustername node=$nodenum"
   if [[ -a $CTROOT/$clustername ]]; then
	print_dbgmsg "cluster $clustername already exists"
	return 1;
   fi

   if [[ $(uname -s) = "AIX" ]]; then
	LC_ALL=C uname -x | read r1 r2 MID junk
   else
	MID=$(uuidgen)
   fi

   # create directories, using the machine ID as the cluster ID
   for name in $CTROOT/cfg \
		$CTROOT/$MID $CTROOT/$MID/cfg  \
		$CTROOT/$MID/lck $CTROOT/$MID/log \
		$CTROOT/$MID/run $CTROOT/$MID/soc
   do
        if [[ ! -a $name ]]; then
                if  mkdir $name
                then
                	chown bin $name
                	chgrp bin $name
                	chmod 775 $name
		fi
        fi
   done

   # link the cluster name
   ln -f -s $CTROOT/$MID $CTROOT/$clustername

   # add this cluster to cluster list file
   print "$MID $clustername" >> $CTROOT/cfg/clusters

   print "$MID" > $CTROOT/cfg/default_cluster
   print "$MID" > $CTROOT/cfg/current_cluster

   print "$nodenum $MID localhost $MID $clustername $nodenum" \
	> $CTROOT/$clustername/cfg/nodedef.cfg

   print_dbgmsg "cluster info creation is done"

   return 0
}


# delete a cluster-def from the clusters file
# input: <clusterid>
function remove_cluster_def_and_dirs
{
    CLSTID=$1
    if [[ -z $CLSTID ]]; then
	return 0
    fi

    echo "$CLSTID" | grep "-"  2>&1 > /dev/null
    if [[ $? -ne 0 ]]; then
	print_dbgmsg "The clusterid $CLSTID is defined as Peer Domain"
	return 1
    fi

    clustername=$(grep -w $CLSTID /var/ct/cfg/clusters | awk '{print $2}')
    if [[ -z $clustername || $clustername = "IW" ]]; then
	# no act...
	return 0
    fi

    grep -v -w $clustername /var/ct/cfg/clusters > /var/ct/cfg/clusters.tmp
    if [[ $? -eq 0 ]]; then
 	mv -f /var/ct/cfg/clusters.tmp /var/ct/cfg/clusters
    fi

    if [[ -n "$CLSTID" && -a /var/ct/$CLSTID ]]; then
        print_dbgmsg "removing $clustername, $CLSTID"
	rm -rf /var/ct/$CLSTID
    fi

    if [[ -n /var/ct/$clustername ]]; then
        print_dbgmsg "cluster $clustername link"
	rm -f /var/ct/$clustername
    fi
}

#
# Wait rmc procs to be stopped, and cleanup SR
# Restart RMC procs as the fresh daemons
# (This function may be called in concurrent mode)
function restart_rmc_procs 
{
    print_dbgmsg "restart_rmc_procs"

    if [[ -x ${RSCTBIN}/rmcctrl ]]; then
	# stop RMC & RMs
	${RSCTBIN}/rmcctrl -z
   	print_dbgmsg "rmc_procs stopped"

	# Reinsert and start RMC 
	${RSCTBIN}/rmcctrl -A
    fi

    print_dbgmsg "rmc_procs restarted"
    return 0
}

#
# This function may be called in non-ConfigRM environments(e.g., GPFS)
# input: clstname nodenum
function rsct_basic_change_cluster_name
{
    #
    CLSTNAME=$1
    NODENUM=$2

    # If clstname or nodenumber is nil, return error
    if [[ -z $CLSTNAME || -z $NODENUM ]]; then
        print_message IMSG_cfghact_Usage $basecmd
	exit 1;
    fi
    
    #
    print_dbgmsg "cfghact CLST=$CLSTNAME NODE=$NODENUM"
    
    #
    # Know whether there is a change 
    # about clstname, number, or current_cluster
    umask 022
    
    #
    # If the desired cluster info does not exist,
    # create the cluster info
    clinfo_changed=0
    if [[ ! -a $CTROOT/$CLSTNAME ]]; then
	create_cluster_info_files $CLSTNAME $NODENUM
	clinfo_changed=1
    fi
    
    # exit if current_cluster info does not exist
    if [[ ! -a $CTROOT/cfg/current_cluster ]]; then
        print_message EMSG104 $basecmd $CTROOT/cfg/current_cluster
	exit 1
    fi
    
    # Get the new cluster info
    NODEDEF_CFG=$CTROOT/$CLSTNAME/cfg/nodedef.cfg
    if [[ -z $NODEDEF_CFG || ! -a ${NODEDEF_CFG} ]]; then
	# node definition file does not exist. 
	print_message EMSG104 $basecmd $NODEDEF_CFG 
	exit 1
    fi
    
    # get the given cluster id & name
    CLSTID=$(grep -w "$CLSTNAME" $CTROOT/cfg/clusters | awk '{print $1}')
    print_dbgmsg "GIVEN CLID=$CTSTID NAME=$CLSTNAME"
    
    # switch the current cluster to new cluster
    set -A CURCLID $(cat $CTROOT/cfg/current_cluster)
    CURCLNAME=$(grep -w "$CURCLID" $CTROOT/cfg/clusters | awk '{print $2}')
    print_dbgmsg "CURRENT CURCLID=$CURCLID CURCLNAME=$CURCLNAME"
    if [[ $CURCLNAME != $CLSTNAME ]]; then
	clinfo_changed=1
    fi
    
    # Check the node number whether they are same
    # if node number is different, update nodedef.cfg
    # and restart RMC/RM subsystems
    #
    # get the current cluster info (as well as old node#)
    set -A clinfo $(cat ${NODEDEF_CFG})
    old_nodenum=${clinfo[0]}        # node number
    old_nodename=${clinfo[2]}       # hostname
    old_clstid=${clinfo[3]}         # clst-id
    old_clstname=${clinfo[4]}       # cluster name
    
    if [[ $old_nodenum != $NODENUM ]]; then
	clinfo_changed=1
	# Replace <NODEDEF_CFG> file with the new node number
	print $NODENUM $old_clstid $old_nodename $old_clstid \
		$CLSTNAME $NODENUM > $NODEDEF_CFG
    fi
    
    #change current_cluster and default_cluster
    if [[ $clinfo_changed -ne 0 ]]; then
	print_dbgmsg "Set the current to $CLSTID, $CLSTNAME, $NODENUM"
	print "$CLSTID" > $CTROOT/cfg/current_cluster
    fi

    # update the default cluster
    set -A DEFCLID $(cat $CTROOT/cfg/default_cluster)
    if [[ ! -a $CTROOT/cfg/default_cluster  || $CLSTID != $DEFCLID ]]; then
	print "$CLSTID" > $CTROOT/cfg/default_cluster
    fi
    
    print_dbgmsg "Current setup ($CLSTID $CLSTNAME $NODENUM) successfully"

    return 0	# success
}

#
# This function will be called BEFORE upgrade
#
function rsct_basic_pre_upgrade
{
    # RMC must be already stopped.
    ##if [[ -x ${RSCTBIN}/rmcctrl ]]
    ##then
    ##	${RSCTBIN}/rmcctrl -z
    ##    rc=$?
    ##    if [[ $rc -ne 0 ]]
    ##    then
    ##        print_message IMSG_Warning_1
    ##    fi
    ##fi

    # (Upgrade) At this momement, ConfigRM should already be stopped.
    # Now time to stop HATS/HATS too if they are running
    if [[ -x ${RSCTBIN}/cthagsctrl ]]; then
	${RSCTBIN}/cthagsctrl -k
    fi
    if [[ -x ${RSCTBIN}/cthatsctrl ]]; then
	${RSCTBIN}/cthatsctrl -k
    fi

    return 0	# success
}

#
function rsct_basic_post_install_or_upgrade
{
    # Link CCAL scripts to cfgmgr if not done already
    for name in ${CCAL_CMDS}
    do
	srcname=${RSCTBIN}/cfgmgr/$name
	tgtname=${RSCTBIN}/$name
	if [[ ! -a $tgtname ]]
	then
		ln -fs $srcname $tgtname
	fi
    done

    # enable the remote connections (when RMC starts)
    enable_rmc_remote_port

    if [[ $AIX_INSTALL -eq 1 ]]; then
	# AIX only...No need to continue
	return 0;
    fi

    if [[ -n $NO_RESTART && $NO_RESTART -eq 1 ]]; then
	# Do not need to proceed...
	return 0
    fi
   
    #.. Re-add RMC subsystem which will rebuild CDB if necessary
    # RMC should be restarted by the installation rpm 
    # So no need to restart RMC here
    ##if [[ -x ${RSCTBIN}/rmcctrl ]]
    ##then
    ##	${RSCTBIN}/rmcctrl -z
    ##	${RSCTBIN}/rmcctrl -A
    ##	rc=$?
    ##	if [[ $rc -ne 0 ]]
    ##	then
    ##        print_message IMSG_Warning_2 $rc
    ##	fi
    ##fi

    # NOTE: HATS/HAGS should be started if non-IW && non-cfgmgr
    if [[ -f ${RSCTBIN}/ct_clusterinfo ]]; then
	clname=`${RSCTBIN}/ct_clusterinfo -c 2> /dev/null`
    fi
    if [[ -z ${clname} ]]; then
	clname=IW       # assume IW mode
    fi

    if [[ -x ${RSCTBIN}/ct_hats_info ]]; then
	ClstEnv=$(${RSCTBIN}/ct_hats_info 2> /dev/null | \
			grep ENVIRONMENT | awk '{print $2}')
    fi
    if [[ -z ${ClstEnv} ]]; then
	ClstEnv="cfgmgr"        # assume it is under cfgmgr
    fi

    is_rpd=$(is_RPD_Name ${clname})
    if [[ X${clname}X != XIWX && $is_rpd -eq 0 ]]; then
	# start HATS/HAGS if necessary
	if [[ -x ${RSCTBIN}/cthatsctrl ]]; then
	     LC_ALL=C lssrc -s cthats > /dev/null 2>&1
	     if [[ $? -eq 0 ]]; then
		# cthats is installed
		${RSCTBIN}/cthatsctrl -s
	     fi
	fi
	if [[ -x ${RSCTBIN}/cthagsctrl ]]; then
	     LC_ALL=C lssrc -s cthags > /dev/null 2>&1
	     if [[ $? -eq 0 ]]; then
		# cthags is installed
		${RSCTBIN}/cthagsctrl -s
             fi
	fi
    fi

    return 0	# success
}

#-----pre-uninstall-------------------
# This function will be called BEFORE upgrade
# Input: -z: uninstall
#        -d: delete subsystems for ALL LC
function rsct_basic_pre_uninst_unupd_delsys
{
    HOW=$1	# one of -d, -z
    # cleanup if ENVIRONMENT is not "cfgmgr"
    if [[ -x ${RSCTBIN}/ct_hats_info ]]; then
	ClstEnv=$(${RSCTBIN}/ct_hats_info 2> /dev/null | \
			grep ENVIRONMENT | awk '{print $2}')
    fi
    if [[ -z ${ClstEnv} ]]; then
	ClstEnv="cfgmgr"
    fi


    # This node must be offline (EXCEPT when INUCLIENT)----------------
    #is_rpd=$(is_RPD_Name ${ClstEnv})
    if [[ ${ClstEnv} = "cfgmgr" && -z "$INUCLIENTS" && -z "$INUBOSTYPE" ]]
    then
	if [[ $HOW = "-z" ]]; then
		/usr/sbin/rsct/install/bin/uncfgrpd
	fi
    fi

    # (Linux) Always stop all resource managers and the rmc daemon
    if [[ $AIX_INSTALL -eq 0 && -x ${RSCTBIN}/rmcctrl ]]
    then
    	${RSCTBIN}/rmcctrl -z
    fi

    # (Uninstall) At this momement, ConfigRM should already be stopped.
    # Now time to stop HATS/HATS too if they are running
    if [[ ( $AIX_INSTALL -eq 0 ||  ${ClstEnv} != "cfgmgr" ) && -z "$INUCLIENTS" && -z "$INUBOSTYPE" ]]; then
	# Linux or non-CfgMgr, and No INUCLIENT only
	if [[ -z "${HOW}" ]]; then
		HOW="-k"
	fi
	if [[ -x ${RSCTBIN}/cthagsctrl ]]; then
		${RSCTBIN}/cthagsctrl -k
		if [[ $HOW != "-k" ]]; then
			${RSCTBIN}/cthagsctrl ${HOW}
		fi
	fi
	if [[ -x ${RSCTBIN}/cthatsctrl ]]; then
		${RSCTBIN}/cthatsctrl -k
		if [[ $HOW != "-k" ]]; then
			$RSCTBIN/cthatsctrl ${HOW}
		fi
	fi
    fi

    if [[ $AIX_INSTALL -eq 0 && -z "$INUCLIENTS" && -z "$INUBOSTYPE" ]]; then

	# switch the current cluster to new cluster
	set -A CURCLID $(cat $CTROOT/cfg/current_cluster)
	CURCLNAME=$(grep -w "$CURCLID" $CTROOT/cfg/clusters | awk '{print $2}')
 
	# for NON-cfgmgr
	if [[  ${ClstEnv} != "cfgmgr" ]]; then
	    # Change the cluster name to "IW" & Node=1
	    rsct_basic_change_cluster_name IW 1

	    # unlink the symbolic links which were created at (-i) time,
	    # and relink them to "cfgmgr" CCAL so that ConfigRM can use them
	    for name in ${CCAL_CMDS}
	    do
		if [[ -a ${RSCTBIN}/$name ]]; then
               		rm -f ${RSCTBIN}/$name
               		ln -fs ${RSCTBIN}/cfgmgr/$name ${RSCTBIN}/$name
		fi
	    done
	fi

	if [[ $HOW = "-z"  || $HOW = "-d" ]]
	then
		#uninstall all non-peer domains (LC)
		clidlist=$(awk '{print $1}' /var/ct/cfg/clusters | grep  "-")
		for clid in $clidlist
		do
			remove_cluster_def_and_dirs $clid
		done
	#else
	#	# remove the cluster def and files
	#	remove_cluster_def_and_dirs $CURCLID
	fi

    fi

    return 0
}


#
# main function starts ----------------------------------
#

print_dbgmsg "$* called"

get_current_locale

# parse the arguments
FORCEFLAG=0
WAITRMC=0
NO_RESTART=0
OPCMD=""
Argcount=0
AIX_INSTALL=0
while getopts ":c:n:fwiKUuzdxIZ" opt
do
    case $opt in
	I )	OPCMD=CfgCtInstall; 	Argcount=$((Argcount+1))
		AIX_INSTALL=1;;
	Z )	OPCMD=CfgCtDeinstall; 	Argcount=$((Argcount+1))
		AIX_INSTALL=1;;
	u )	OPCMD=postupgrade;	Argcount=$((Argcount+1));;
	i )	OPCMD=postinstall;	Argcount=$((Argcount+1));;
	U )	OPCMD=preupgrade;	Argcount=$((Argcount+1));;
	z )	OPCMD=predeinstall;	Argcount=$((Argcount+1));;
	d )	OPCMD=del_all_LC;	Argcount=$((Argcount+1));;
	c )     OPCMD=change;		Argcount=$((Argcount+1))
		CLSTNAME=$OPTARG;;      # cluster name
	n )     NODENUM=$OPTARG;;    # node number
	f )	FORCEFLAG=1;;		#force RMC
	x )	NO_RESTART=1;;	#network_install
	w )	WAITRMC=1;;		# (sync) wait till RMC done
        h )     print_message IMSG_cfghact_Usage $basecmd
                exit 0;;
        ? ) print_message EMSG100 $basecmd $OPTARG
                exit 1;;
    esac
done

if ((Argcount == 0))
then
        # no argument specified
        print_message EMSG101 $basecmd 
        print_message IMSG_cfghact_Usage $basecmd
	exit 1
fi

if ((Argcount > 1))
then
        # More than one argument specified 
        print_message EMSG102 $basecmd 
        print_message IMSG_cfghact_Usage $basecmd
	exit 1
fi

rc=0
case $OPCMD in
    preupgrade )
	rsct_basic_pre_upgrade
	exit $?
	;;

    del_all_LC )

	# delete only LC domains
	# Note: RMC should be handled by outside (rpm)
        #LC_ALL=C lssrc -s ctrmc > /dev/null 2>&1
        #rmc_not_installed=$?        # rmc installed?

	rsct_basic_pre_uninst_unupd_delsys  -d
	rc=$?

        #if [[ -z $NO_RESTART || $NO_RESTART -eq 0 ]]; then
	#	if [[ $rmc_not_installed -eq 0 ]]; then
	#		restart_rmc_procs
	#	fi
        #fi

	exit $rc
	;;

    predeinstall )

	# Note: RMC should be handled by outside (rpm)
        #LC_ALL=C lssrc -s ctrmc > /dev/null 2>&1
        #rmc_not_installed=$?        # rmc installed?

	rsct_basic_pre_uninst_unupd_delsys  -z
	rc=$?

        #if [[ -z $NO_RESTART || $NO_RESTART -eq 0 ]]; then
	#	if [[ $rmc_not_installed -eq 0 ]]; then
	#		restart_rmc_procs
	#	fi
        #fi

	exit $rc
	;;

    CfgCtInstall )
	rsct_basic_post_install_or_upgrade

	# Options (-p) to enable the remote port, and (-r) rebuild CDB
	/usr/sbin/rsct/install/bin/ctinstall -t I -p -r -f rsct.basic.rte -g RSCT_ALL
	exit $?
	;;

    CfgCtDeinstall )
	rsct_basic_pre_uninst_unupd_delsys  -z

	# Options (-r) to rebuild CDB
        /usr/sbin/rsct/install/bin/ctinstall -t D -r -f rsct.basic.rte -g RSCT_ALL
        exit $?
	;;

    postinstall | postupgrade )
	if [[ $FORCEFLAG -ne 0 ]]; then
		rsct_basic_pre_upgrade
	fi
	rsct_basic_post_install_or_upgrade
	exit $?
	;;

    change )

	# Note: RMC should be handled by outside (rpm)
	#LC_ALL=C lssrc -s ctrmc > /dev/null 2>&1
	#rmc_not_installed=$?        # rmc installed?

	rsct_basic_change_cluster_name $CLSTNAME $NODENUM

	# ask to stop rmc... Not true anymore
	# RMC does not need to be restarted for non-RPD domain
	# because RMC will continue to see "IW" even under GPFS or scaffold
	# 
	##if [[ 0 -ne 0  && $rmc_not_installed -eq 0 ]]; then
	##    if [[ $FORCEFLAG -ne 0 || $clinfo_changed -ne 0 ]]; then
	##	 stop and restart rmc procs
	##        if [[ $WAITRMC -ne 0 ]]; then
	##		#synchrous
	##			restart_rmc_procs
	##	else
	##		#(CONCURRENTLY)
	##		restart_rmc_procs &
	##	fi
	##    fi
	##fi

	exit $? ;;
esac

exit 0
